package org.jeecg.common.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;

import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.FillRuleConstant;
import org.jeecg.common.entity.ConstantApp;
import org.jeecg.common.entity.SysDepart;
import org.jeecg.common.entity.SysDepartTreeModel;
import org.jeecg.common.entity.SysPosition;
import org.jeecg.common.entity.vo.SysDepartVO;
import org.jeecg.common.mapper.SysDepartMapper;
import org.jeecg.common.service.ISysDepartService;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.FillRuleUtil;
import org.jeecg.common.util.YouBianCodeUtil;
import org.jeecg.common.util.oConvertUtils;
import com.jeecg.weibo.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;


/**
 * <p>
 * 部门表 服务实现类
 * <p>
 *
 * @Author 国子软件
 * @Since 2019-01-22
 */
@Slf4j
@Service
public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart> implements ISysDepartService {


    @Resource
    private SysDepartMapper sysDepartMapper;

    @Autowired
    ISysDepartService departService;



    /**
     * 返回全名称
     *
     * @param parentData
     * @param sysDepart
     * @return
     */
    private String getFn(JSONObject parentData, SysDepart sysDepart) {
        JSONObject parentMap = parentData.getJSONObject("parentMap");
        LinkedList<String> orgName = new LinkedList();
        orgName.addFirst(sysDepart.getDepartName());
        //地柜拼接名称列表
        setFn(orgName, parentMap, sysDepart.getParentId());
        StringBuffer sb = new StringBuffer();
        for (String deptNameEn : orgName) {
            sb.append(deptNameEn);
        }
        return sb.toString();
    }

    /**
     * 递归获取全名称集合
     *
     * @param orgName
     * @param parentMap
     * @param parentId
     */
    private void setFn(LinkedList orgName, JSONObject parentMap, String parentId) {
        if (parentMap != null) {
            JSONObject currentOrg = parentMap.getJSONObject(parentId);
            String deptName = currentOrg.getString("departName");
            orgName.addFirst(deptName);
            String cParentId = currentOrg.getString("parentId");
            if (!org.jeecg.common.util.StringUtils.equals(cParentId, "")) {
                setFn(orgName, parentMap, cParentId);
            }
        }
    }

    /**
     * 根据parentId查询部门树
     *
     * @param parentId
     * @param ids      前端回显传递
     * @return
     */
    @Override
    //@Cacheable(cacheNames = "qTLBP")
    public List<SysDepartTreeModel> queryTreeListByPid(String parentId, String ids) {
        Consumer<LambdaQueryWrapper<SysDepart>> square = i -> {
            if (oConvertUtils.isNotEmpty(ids)) {
                i.in(SysDepart::getId, ids.split(","));
            } else {
                if (oConvertUtils.isEmpty(parentId)) {
                    i.and(q -> q.isNull(true, SysDepart::getParentId).or().eq(true, SysDepart::getParentId, ""));
                } else {
                    i.eq(true, SysDepart::getParentId, parentId);
                }
            }
        };
        LambdaQueryWrapper<SysDepart> lqw = new LambdaQueryWrapper<>();
        lqw.eq(true, SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
        lqw.func(square);
        lqw.orderByAsc(SysDepart::getDepartOrder);
        List<SysDepart> list = list(lqw);
        List<SysDepartTreeModel> records = new ArrayList<>();
        HashMap leafs = new HashMap<>();
        List<HashMap<String, String>> leafsList = new ArrayList<>();

        //数据库写死第一节点ID是843
        if (oConvertUtils.isEmpty(parentId)) {
            leafs.put("1", 2);
        } else {
            leafsList = this.baseMapper.queryTreeMapByPid(parentId);
            for (HashMap<String, String> leafMap : leafsList) {
                leafs.put(leafMap.get("parent_id"), leafMap.get("count"));
            }
        }

        for (int i = 0; i < list.size(); i++) {
            SysDepart depart = list.get(i);
            SysDepartTreeModel treeModel = new SysDepartTreeModel(depart);
            //TODO 异步树加载key拼接__+时间戳,以便于每次展开节点会刷新数据
            treeModel.setKey(treeModel.getKey());

            if (!leafs.containsKey(depart.getId())) {
                treeModel.setIsLeaf(true);
            } else {
                treeModel.setIsLeaf(false);
            }
            records.add(treeModel);
        }
        return records;
    }

    @Override
    public List<SysDepartTreeModel> queryTreeListByPidWithSelf(String parentId, String ids) {
        Consumer<LambdaQueryWrapper<SysDepart>> square = i -> {
            if (oConvertUtils.isNotEmpty(ids)) {
                i.in(SysDepart::getId, ids.split(","));
            } else {
                if (oConvertUtils.isEmpty(parentId)) {
                    i.and(q -> q.isNull(true, SysDepart::getParentId).or().eq(true, SysDepart::getParentId, ""));
                } else {
                    i.eq(true, SysDepart::getId, parentId);//增加本级查询方便各单位管理员进行下属机构维护
                }
            }
        };
        LambdaQueryWrapper<SysDepart> lqw = new LambdaQueryWrapper();
        lqw.eq(true, SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
        lqw.func(square);
        lqw.orderByAsc(SysDepart::getDepartOrder);
        List<SysDepart> list = list(lqw);
        List<SysDepartTreeModel> records = new ArrayList<>();
        HashMap leafs = new HashMap<>();
        List<HashMap<String, String>> leafsList = new ArrayList<>();

        //数据库写死第一节点ID是843
        if (oConvertUtils.isEmpty(parentId)) {
            leafs.put("1", 2);
        } else {
            leafsList = this.baseMapper.queryTreeMapByPidWithSelf(parentId);
            for (HashMap<String, String> leafMap : leafsList) {
                leafs.put(leafMap.get("parent_id"), leafMap.get("count"));
            }
        }

        for (int i = 0; i < list.size(); i++) {
            SysDepart depart = list.get(i);
            SysDepartTreeModel treeModel = new SysDepartTreeModel(depart);
            //TODO 异步树加载key拼接__+时间戳,以便于每次展开节点会刷新数据
            treeModel.setKey(treeModel.getKey());

            if (!leafs.containsKey(depart.getId())) {
                treeModel.setIsLeaf(true);
            } else {
                treeModel.setIsLeaf(false);
            }
            records.add(treeModel);
        }
        return records;
    }




    /**
     * 递归调用查询父部门接口
     */
    private void queryAllParentIdRecursion(String fieldName, String value, JSONObject data) {
        QueryWrapper<SysDepart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(fieldName, value);
        SysDepart depart = super.getOne(queryWrapper);
        if (depart != null) {
            data.getJSONArray("parentIds").add(0, depart.getId());
            data.getJSONObject("parentMap").put(depart.getId(), depart);
            if (oConvertUtils.isNotEmpty(depart.getParentId())) {
                this.queryAllParentIdRecursion("id", depart.getParentId(), data);
            }
        }
    }




    @Override
    public List<SysDepartTreeModel> queryDepartTreeByOrgCode(String id) {
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<>();
        query.eq(SysDepart::getId, id);
        SysDepart root = this.getOne(query);
        List<SysDepartTreeModel> list = this.queryDepartTreeByParentId(root.getId());
        SysDepartTreeModel tree = new SysDepartTreeModel(root);
        //get sys depart tree model recursively
        if (list.size() > 0) {
            tree.setChildren(list);
            for (SysDepartTreeModel item : list) {
                List<SysDepartTreeModel> children = this.queryDepartTreeByParentId(item.getId());
                if (children.size() > 0) {
                    item.setChildren(queryDepartTreeByOrgCode(item.getId()));
                } else {
                    item.setIsLeaf(true);
                }
            }
        }
        return list;
    }

    private List<SysDepartTreeModel> queryDepartTreeByParentId(String parentId) {
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<>();
        query.eq(SysDepart::getParentId, parentId);
        query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0);
        List<SysDepart> list = this.list(query);
        List<SysDepartTreeModel> treeList = new ArrayList<>();
        for (SysDepart depart : list) {
            SysDepartTreeModel tree = new SysDepartTreeModel(depart);
            treeList.add(tree);
        }
        return treeList;
    }


}
